package yd

import (
	"crypto/hmac"
	"crypto/sha256"
	"encoding/base64"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"net/http"
	"strings"
	"time"
)

type MobSDK struct {
	SecretId  string
	SecretKey string
	BaseUrl   string
}

const (
	StandUrl = "https://pnt.10086.cn/v1/gateway/api/openapi/hapmall/"
	TestUrl  = "https://zjpnt-pp.cmiov.cn:58086/v1/gateway/api/openapi/hapmall/"
	Pjson    = "application/json;"
)

// 月账号、天账号
// 年账号、月账号、周账号、天账号
// ToV 场景-过期时间字段会进行相关计算
// 仅适用于无需商品信息的场景
var AccType = [4]string{"/diffAccount/oapi/list", "/v2/diffAccount/oapi/list", "/tov/diffAccount/oapi/list", "/diffaccount/diffAccount/oapi/list"}

// 创建
func NewMobSDK(secretid, secretkey string, isStand bool) *MobSDK {
	baseurl := StandUrl
	if !isStand {
		baseurl = TestUrl
	}
	return &MobSDK{
		secretid,
		secretkey,
		baseurl,
	}
}

// 获取标签
func (this *MobSDK) sign(url string) (string, int64) {
	l := time.Now().UnixMilli()
	stringToSign := fmt.Sprint(this.SecretId, l, "POST", url)
	h := hmac.New(sha256.New, []byte(this.SecretKey))
	h.Write([]byte(stringToSign))
	sha := hex.EncodeToString(h.Sum(nil))
	return base64.StdEncoding.EncodeToString([]byte(sha)), l
}

// 统一设置请求头
func SetRequestHeader(request *http.Request, secretId, sign string, l int64) {
	request.Header.Set("secretId", secretId)
	request.Header.Set("timeStamp", fmt.Sprintf("%d", l))
	request.Header.Set("sign", sign)
}

// 拉取用户账号列表
/*
{
"accountType": "ON_FORMAL",
"activateStatus": "ACTIVATED",
"activateTimeStart": "2021-02-04 17:55:05",
"activateTimeEnd": "2021-02-04 17:58:05",
"createdTimeStart": "2021-02-04 17:54:03",
"createdTimeEnd": "2021-02-04 17:55:03",
"diffAccountNo": "acgf4698",
"expireTimeStart": "2021-03-04 17:55:05",
"expireTimeEnd": "2021-03-04 17:67:05",
"finalActTimeStart": "2021-02-04 17:55:05",
"finalActTimeEnd": "2021-02-04 17:58:05",
"goodsName": "外部亚米级 RTK 商品",
"loginType": 1,
"orderNo": "304623268588060672"
}
*/
func (this *MobSDK) GetUserAccountList(reqType int, paramsString string) (string, error) {
	url := this.BaseUrl + AccType[reqType]
	sign, l := this.sign(url)
	res, err := Post(url, Pjson, paramsString, func(request *http.Request) {
		SetRequestHeader(request, this.SecretId, sign, l)
	}, nil)
	if err != nil {
		return "", err
	}
	fmt.Println(res)
	if res["code"] != "000_0000_0000" {
		return "", fmt.Errorf("请求失败:" + res["message"].(string))
	}
	jstr, err := json.Marshal(res)
	if err != nil {
		return "", err
	}
	return string(jstr), nil
}

// 修改指定账号的密码
func (this *MobSDK) ResetPassWord(accountid, newpwd string) error {
	sign, l := this.sign(this.BaseUrl + "/diffAccount/oapi/reset/password")
	res, err := Post(this.BaseUrl+"/diffAccount/oapi/reset/password", Pjson, fmt.Sprintf(`{
   "diffAccount":"%s",
   "password":"%s"
}`, accountid, newpwd), func(request *http.Request) {
		SetRequestHeader(request, this.SecretId, sign, l)
	}, nil)
	if err != nil {
		return err
	}
	fmt.Println(res)
	if res["code"] != "000_0000_0000" {
		return fmt.Errorf("请求失败:" + res["message"].(string))
	}
	return nil
}

// 激活指定账号
func (this *MobSDK) ActiveAcc(accountid string) error {
	url := this.BaseUrl + "/v1/webapi/diffAccount/activate"
	sign, l := this.sign(url)
	res, err := Post(url, Pjson, fmt.Sprintf(`{"diffAccount":"%s"}`, accountid), func(request *http.Request) {
		SetRequestHeader(request, this.SecretId, sign, l)
	}, nil)
	if err != nil {
		return err
	}
	if res["code"] != "000_0000_0000" {
		return fmt.Errorf("请求失败:" + res["message"].(string))
	}
	return nil
}

// 批量激活
func (this *MobSDK) BatchActive(acclist []string) error {
	str := ""
	for _, v := range acclist {
		str += "\"" + v + "\","
	}
	str = strings.TrimSuffix(str, ",")
	url := this.BaseUrl + "/v1/webapi/diffAccount/batchActivate"
	sign, l := this.sign(url)
	res, err := Post(url, Pjson, fmt.Sprintf(`{
"diffAccountList":[%s]
}`, str), func(request *http.Request) {
		SetRequestHeader(request, this.SecretId, sign, l)
	}, nil)
	if err != nil {
		return err
	}
	if res["code"] != "000_0000_0000" {
		return fmt.Errorf("请求失败:" + res["message"].(string))
	}
	return nil
}

// 启用差分账号
func (this *MobSDK) EnableAcc(accountid string) error {
	url := this.BaseUrl + "/v1/webapi/diffAccount/enabled"
	sign, l := this.sign(url)
	res, err := Post(url, Pjson, fmt.Sprintf(`{
"diffAccountList":"%s"
}`, accountid), func(request *http.Request) {
		SetRequestHeader(request, this.SecretId, sign, l)
	}, nil)
	if err != nil {
		return err
	}
	if res["code"] != "000_0000_0000" {
		return fmt.Errorf("请求失败:" + res["message"].(string))
	}
	return nil
}

// 批量启用账号
func (this *MobSDK) BatchEnableAcc(acclist []string) error {
	str := ""
	for _, v := range acclist {
		str += "\"" + v + "\","
	}
	str = strings.TrimSuffix(str, ",")
	url := this.BaseUrl + "/v1/webapi/diffAccount/batchEnabled"
	sign, l := this.sign(url)
	res, err := Post(url, Pjson, fmt.Sprintf(`{
"diffAccountList":[%s]
}`, str), func(request *http.Request) {
		SetRequestHeader(request, this.SecretId, sign, l)
	}, nil)
	if err != nil {
		return err
	}
	if res["code"] != "000_0000_0000" {
		return fmt.Errorf("请求失败:" + res["message"].(string))
	}
	return nil
}

// 禁用差分账号
func (this *MobSDK) DisableAcc(accountid string) error {
	url := this.BaseUrl + "/v1/webapi/diffAccount/disable"
	sign, l := this.sign(url)
	res, err := Post(url, Pjson, fmt.Sprintf(`{
"diffAccountList":"%s"
}`, accountid), func(request *http.Request) {
		SetRequestHeader(request, this.SecretId, sign, l)
	}, nil)
	if err != nil {
		return err
	}
	if res["code"] != "000_0000_0000" {
		return fmt.Errorf("请求失败:" + res["message"].(string))
	}
	return nil
}

// 批量禁用
func (this *MobSDK) BatchDisableAcc(acclist []string) error {
	str := ""
	for _, v := range acclist {
		str += "\"" + v + "\","
	}
	str = strings.TrimSuffix(str, ",")
	url := this.BaseUrl + "/v1/webapi/diffAccount/batchDisable"
	sign, l := this.sign(url)
	res, err := Post(url, Pjson, fmt.Sprintf(`{
"diffAccountList":[%s]
}`, str), func(request *http.Request) {
		SetRequestHeader(request, this.SecretId, sign, l)
	}, nil)
	if err != nil {
		return err
	}
	if res["code"] != "000_0000_0000" {
		return fmt.Errorf("请求失败:" + res["message"].(string))
	}
	return nil
}

func Post(url string, contentType string, params string, SetReq func(*http.Request), GetResp func(*http.Response)) (map[string]interface{}, error) {
	request, err := http.NewRequest("POST", url, strings.NewReader(params)) //请求主体
	if err != nil {
		return nil, err
	}
	request.Header.Set("Content-Type", contentType) //设置请求头
	return Do(request, SetReq, GetResp)
}

func Do(request *http.Request, SetReq func(*http.Request), GetResp func(*http.Response)) (map[string]interface{}, error) {
	client := http.Client{}
	if SetReq != nil {
		SetReq(request) //请求
	}
	resp, err := client.Do(request)
	if err != nil {
		fmt.Println(err.Error())
		return nil, err
	}
	defer resp.Body.Close()
	if GetResp != nil {
		GetResp(resp) //响应
	}
	var result map[string]interface{}
	err = json.NewDecoder(resp.Body).Decode(&result)
	if err != nil {
		return nil, err
	}
	return result, nil
}
